package com.lishuang.basic.service.impl;


import com.lishuang.basic.constant.VerifyCodeConstants;
import com.lishuang.basic.dto.SmsCodeDto;
import com.lishuang.basic.exception.BusinessException;
import com.lishuang.basic.service.IVerifyService;
import com.lishuang.basic.util.StrUtils;
import com.lishuang.basic.util.VerifyCodeUtils;
import com.lishuang.user.domain.User;
import com.lishuang.user.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;

@Service
public class VerifyServiceImpl implements IVerifyService {

    @Autowired
    @Qualifier("redisTemplate")
    private RedisTemplate redisTemplate;

    @Autowired
    private UserMapper userMapper;

    /**
     * 获取图形验证码
     *
     * @param key
     * @return
     */
    @Override
    public String getImgCode(String key) {
        //判断key是否为空
        if (StringUtils.isEmpty(key)) {
            throw new BusinessException("key为空");
        }

        //获取随机验证码
        String code = VerifyCodeUtils.generateVerifyCode(4);
        //将验证码存放到redis，设置5分钟过期
        redisTemplate.opsForValue().set(key, code, 5, TimeUnit.MINUTES);

        //把验证码的值合并到图片，使用Base64编码。并返回base64编码的字符串
        return VerifyCodeUtils.verifyCode(115, 40, code);
    }

    /**
     * 获取手机验证码接口
     *
     * @param smsCodeDto
     * @return
     */
    @Override
    public void sendSmsCode(SmsCodeDto smsCodeDto) {
        String phone = smsCodeDto.getPhone();
        String imageCode = smsCodeDto.getImageCode();
        String imageCodeKey = smsCodeDto.getImageCodeKey();

        //1.校验 - 空值校验
        if (StringUtils.isEmpty(phone)) {
            throw new BusinessException("电话号码不能为空。。。");
        }
        if (StringUtils.isEmpty(imageCode)) {
            throw new BusinessException("图片验证码不能为空。。。");
        }
        if (StringUtils.isEmpty(imageCodeKey)) {
            throw new BusinessException("请重新点击获取图片验证码。。。");
        }

        //2.校验 - 图形验证码校验 - 是否过期
        Object redisImageCode = redisTemplate.opsForValue().get(imageCodeKey);
        if (redisImageCode == null) {
            throw new BusinessException("图形验证码失效。。。");
        }

        //3.校验 - 图形验证码校验 - 是否正确
        if (!imageCode.equalsIgnoreCase(redisImageCode.toString())) {
            throw new BusinessException("图形验证码输入错误。。。");
        }

        //4.校验 - 手机号码是否注册过
        //为什么要用User不用Logininfo：其实可以用Logininfo去查询，但是需要多传入一个type
        User user = userMapper.loadByPhone(phone);
        if (user != null) {
            throw new BusinessException("该电话号码已经注册，请直接登录，忘记密码请联系管理员。。。");
        }

        //5.获取手机验证码 - 判断是否过期 // 9527:1233555555
        Object redisSmsCode = redisTemplate.opsForValue().get(VerifyCodeConstants.REGISTER_CODE_PREFIX + phone);
        String code = null;
        //第一次发送 or 手机验证码过期了
        if (redisSmsCode == null) {
            //过期了就用新的验证码
            code = StrUtils.getComplexRandomString(6);
        } else { //没有过期
            //验证是否过了重发时间
            //以前保存的时间
            long redisTime = Long.parseLong(redisSmsCode.toString().split(":")[1]);
            //现在的时间
            long nowTime = System.currentTimeMillis();

            //6.没有过期 - 判断是否过了重发时间
            if ((nowTime - redisTime) < (1 * 60 * 1000)) {
                //没有过重发时间
                throw new BusinessException("请勿重复获取验证码。。。");
            } else {
                //没有过期就用以前的验证码
                code = redisSmsCode.toString().split(":")[0];
            }
        }

        //7.将验证码存入redis：【register:18725556563 - 9527:1233555555】
        //刷新了过期时间
        redisTemplate.opsForValue().set(VerifyCodeConstants.REGISTER_CODE_PREFIX + phone, code + ":" + System.currentTimeMillis(), 3, TimeUnit.MINUTES);

        //8.调用SmsUtils发送短信
        //SmsUtil.sendSms(phone,"手机验证码为：" + code + ",请在3分钟内使用!!!");
        System.out.println("手机验证码为：" + code + ",请在3分钟内使用!!!");
    }

    @Override
    public void binderSmsCode(SmsCodeDto smsCodeDto) {
        //校验 - 空值校验
        String phone = smsCodeDto.getPhone();
        if(StringUtils.isEmpty(phone)){
            throw new BusinessException("手机号不可为空");
        }

        //获取手机验证码 - 判断是否过期 // 9527:1233555555
        Object redisSmsCode = redisTemplate.opsForValue().get(VerifyCodeConstants.BINDER_CODE_PREFIX + phone);
        String code = null;
        //第一次发送 or 手机验证码过期了
        if (redisSmsCode == null) {
            //过期了就用新的验证码
            code = StrUtils.getComplexRandomString(6);
        } else { //没有过期
            //验证是否过了重发时间
            //以前保存的时间
            long redisTime = Long.parseLong(redisSmsCode.toString().split(":")[1]);
            //现在的时间
            long nowTime = System.currentTimeMillis();

            //6.没有过期 - 判断是否过了重发时间
            if ((nowTime - redisTime) < (1 * 60 * 1000)) {
                //没有过重发时间
                throw new BusinessException("请勿重复获取验证码。。。");
            } else {
                //没有过期就用以前的验证码
                code = redisSmsCode.toString().split(":")[0];
            }
        }

        //7.将验证码存入redis：【register:18725556563 - 9527:1233555555】
        //刷新了过期时间
        redisTemplate.opsForValue().set(VerifyCodeConstants.BINDER_CODE_PREFIX + phone, code + ":" + System.currentTimeMillis(), 3, TimeUnit.MINUTES);

        //8.调用SmsUtils发送短信
        //SmsUtil.sendSms(phone,"手机验证码为：" + code + ",请在3分钟内使用!!!");
        System.out.println("手机验证码为：" + code + ",请在3分钟内使用!!!");
    }
}